<?php

App::import('Model', 'Building');
App::import('Model', 'LookupValue');
App::import('Model', 'PaymentDue');

class Expense extends AppModel {

    var $name = 'Expense';
    var $primaryKey = 'expense_id';
    //The Associations below have been created with all possible keys, those that are not needed can be removed
    var $belongsTo = array(
        'Property' => array(
            'className' => 'Property',
            'foreignKey' => 'property_id',
            'conditions' => '',
            'fields' => '',
            'order' => ''
        ),
        'RefinancingPlan' => array(
            'className' => 'RefinancingPlan',
            'foreignKey' => 'refinancing_plan_id',
            'conditions' => '',
            'fields' => '',
            'order' => ''
        ),
        'ExpenditureTypeSource' => array(
            'className' => 'LookupValue',
            'foreignKey' => 'expenditure_type_source',
            'conditions' => array('ExpenditureTypeSource.lookup_type' => 'EXPENDITURE_TYPE_SOURCE'),
            'order' => 'ExpenditureTypeSource.meaning'
        )
    );

    function getFirstDueDate($payment_data) {
        $first_due_day = $payment_data['first_due_date'];
        $month = date('m');
        $year = date('Y');
        $first_date = $year . '-' . $month . '-' . $first_due_day;
        return $first_date;
    }

    function getSecondDueDate($payment_data) {
        $second_due_day = $payment_data['second_due_date'];
        $month = date('m');
        $year = date('Y');
        $second_date = $year . '-' . $month . '-' . $second_due_day;
        return $second_date;
    }

    function getBuildingDailyRate($payment_data) {
        $daily_rate = $payment_data['annual_rate'] / 365;
        return($daily_rate);
    }

    function getBuildingInterestScheme($payment_data) {
        $building = new Building();
        $scheme = $building->obtenerInterestSchemeType($payment_data);
        return($scheme);
    }
    
    function getExpenseFinantialInformation($data){
        $build_id = $data['Property']['building_id'];
        $building = new Building();
        $building_data = $building->read(null,$build_id);
        $payment_data = $building_data['PaymentDue'];
        $interest_scheme = $this->getBuildingInterestScheme($payment_data);
        $last_payment_date = $data['Expense']['payment_date'];

        $expenseFinantialInfo = array();
        $expenseFinantialInfo['amount'] = round($data['Expense']['amount'],2);
        $expenseFinantialInfo['previous_debt'] = round($data['Expense']['previous_debt'],2);
        $expenseFinantialInfo['payment_amount'] = round($data['Expense']['payment_amount'],2);
        $expenseFinantialInfo['interest(%)'] = $this->getBuildingDailyRate($payment_data) * 100;
        $expenseFinantialInfo['next_month_interests'] = 0;
        $expenseFinantialInfo['month_new_interests'] = 0;

        // Controlo vencimientos
        $first_due = $this->getFirstDueDate($payment_data);
        $first_gap = $this->gapDates($first_due);
        $second_due = $this->getSecondDueDate($payment_data);
        $second_gap = $this->gapDates($second_due);
        $last_payment_gap = date("j")-1; // si no hubo pago
        // Si ya se realizó un pago, calculo el gap respecto de la última vez
        // que se calcularon los intereses
        if (!is_null($last_payment_date)){
            $last_payment_gap = $this->gapDates($last_payment_date);
        }
        $overdue_gap = 0;

        // Controlo primer vencimiento
        if (($first_gap > 0) && ($interest_scheme != "SECOND_DUE_DATE")) {
            $overdue_gap = min($first_gap,$last_payment_gap);
        }
        else if (($first_gap > 0) && ($interest_scheme == "SECOND_DUE_DATE")){
            $expenseFinantialInfo['amount'] = round($data['Expense']['second_due_amount'],2);
            //Controlo segundo vencimiento
            if ($second_gap > 0){
                $overdue_gap = min($second_gap,$last_payment_gap);
            }
        }
        // El propietario pudo haber pagado parcialmente, y no todo va al interes
        $amount_interest = 0;
        $debt = $expenseFinantialInfo['amount'] + $data['Expense']['interests'] + $data['Expense']['previous_debt'] - $data['Expense']['payment_amount'];
        $amount_debt = min($debt,$expenseFinantialInfo['amount']);
        $amount_interest = $amount_debt*$overdue_gap*$this->getBuildingDailyRate($payment_data);

        // Intereses de deuda previa
        $previous_debt = $data['Expense']['interests'] + $data['Expense']['previous_debt'] - $data['Expense']['payment_amount'];
        $previous_debt_amount = min($previous_debt, $data['Expense']['previous_debt']);
        $previous_debt_interests = 0;
        if ($previous_debt_amount > 0){
            $previous_debt_interests = $previous_debt_amount*$last_payment_gap*$this->getBuildingDailyRate($build_id);
        }
        if ($interest_scheme == "DEFERRED") {
            $expenseFinantialInfo['next_month_interests'] = $amount_interest+$previous_debt_interests;
            $expenseFinantialInfo['interests'] = round($data['Expense']['interests'],2);
        }
        else {
            $expenseFinantialInfo['month_new_interests'] = $amount_interest+$previous_debt_interests;
            $expenseFinantialInfo['interests'] = round($data['Expense']['interests']+$amount_interest+$previous_debt_interests,2);
        }

        $expenseFinantialInfo['interests_debt'] = max(0,$expenseFinantialInfo['interests'] - $expenseFinantialInfo['payment_amount']);
        $expenseFinantialInfo['amount_debt'] = max(0,$expenseFinantialInfo['interests'] + $expenseFinantialInfo['previous_debt'] - $expenseFinantialInfo['payment_amount']);;
        $expenseFinantialInfo['expense_debt'] = max(0,$expenseFinantialInfo['interests'] + $expenseFinantialInfo['previous_debt'] + $expenseFinantialInfo['amount'] - $expenseFinantialInfo['payment_amount']);;
        $expenseFinantialInfo['debt'] = round($expenseFinantialInfo['amount'] + $expenseFinantialInfo['previous_debt'] + $expenseFinantialInfo['interests'] - $expenseFinantialInfo['payment_amount'],2);
       
        return $expenseFinantialInfo;
    }

    // Devuelve la diferencia entre 2 fechas en dias. Aclaracion Miguel: entre una fecha y la actual
    // Formato de YYYY-MM-DD
    function gapDates($data1) {
        $data2 = date("Y-m-d");
        // 86400 seg = 60 [seg/1_minuto] * 60 [1_minuto / 1_hora]* 24 [1_hora]

        $second = strtotime($data2) - strtotime($data1);
        if ($second > 0) {
            $days = intval($second / 86400);
            $sl_retorna = $days;
            return $sl_retorna;
        }else
            return 0;
    }

    //diferencia de dias entre dos fechas arbitrarias
    function gapDatesPeriodo($date1, $date2) {
        $date_format = substr($date1, 0, 10);
        $date_format2 = substr($date2, 0, 10);

        $datetime1 = new DateTime($date_format);
        $datetime2 = new DateTime($date_format2);
        $interval = $datetime1->diff($datetime2, true);

        return($interval->format('%a'));
    }

    // Devuelve la diferencia en dias de $dateTo - $dateFrom
    // Puede ser negativo
    function getDatePeriodGap($dateFrom, $dateTo){
        $gap_data = $dateFrom->diff($dateTo, false);
        $sign = 1-2*$gap_data->invert;
        $days = $gap_data->days;
        $result = $sign*$days;
        
        return $result;
    }


    function getResponsible() {
        // si la expensa es extraordinaria, el responsable es el propietario.
        // si la expensa es ordinaria, el responsable es el inquilino, apoderado,
        // propietario, apoderado del propietario en ese orden.
        $property = $this->Property->find('first');

        if ($this->data['Expense']['expenditure_type_source'] == '5') {// REGULAR
            $responsible = $property->Tenant->find('first');

            if ($responsible == null) {
                $responsible = $property->TenantRepresentative->find('first');
            }
        }

        if ($responsible == null)
            $responsible = $property->Owner->find('first');

        if ($responsible == null)
            $responsible = $property->OwnerRepresentative->find('first');

        return $responsible;
    }

    function getExpenditureTypeSource($expense_data) {
        $lookupVal = new LookupValue();
        $lookupVal_data = $lookupVal->read(null, $expense_data['expenditure_type_source']);
        return $lookupVal_data['LookupValue']['lookup_code'];
    }

}

?>
